<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>一文彻底了解Android自定义控件3 | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6auv000d7kny7pvh2hbw" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      一文彻底了解Android自定义控件3
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-06-11T21:37:27.000Z" itemprop="datePublished">2020-06-12</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <h3 id="Android自定控件的步骤"><a href="#Android自定控件的步骤" class="headerlink" title="Android自定控件的步骤"></a>Android自定控件的步骤</h3><p>为什么自定义控件要步骤化呢？因为很多新手同学，根据产品的要求做一些控件时，无从下手。</p>
<p>有了步骤以后，就可以按套路走了，再也不用害怕了。</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877ef78f4537d?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<a id="more"></a>

<h3 id="判断控件类型"><a href="#判断控件类型" class="headerlink" title="判断控件类型"></a>判断控件类型</h3><p>首先我们要判断这个控件是属于自定义控件里的哪种类型，如果不知道分类的话，同学们可以看这篇文章<code>自定义控件分类</code></p>
<h3 id="获取相关的属性"><a href="#获取相关的属性" class="headerlink" title="获取相关的属性"></a>获取相关的属性</h3><p>其实这玩意在自定义控件里叫自定义属性。什么是属性呢？</p>
<p>来我们看，android控件原有的属性：</p>
<p>比如说我们的LinearLayout</p>
<pre><code>&lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_alignParentBottom=&quot;true&quot;
        android:layout_centerHorizontal=&quot;true&quot;
        android:layout_marginBottom=&quot;41px&quot;
        android:orientation=&quot;horizontal&quot;&gt;
&lt;/LinearLayout&gt;</code></pre>
<p>这里面的属性就有origintation,layout_width,layout_height…. 而origintation是LinearLayout特有的，而其他的则是View都有的</p>
<p>那么我们在写自己的控件时，有些值，也是通过xml里的属性进行配置的，所以我们要有自定义属性。</p>
<p>自定义控件里如何自定义属性呢？</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877f3cbbdbf4e?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877f63897a169?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>自定义属性步骤：</p>
<ol>
<li>声明属性</li>
</ol>
<p>在<code>res</code>的<code>values</code>目录下的<code>attrs.xml</code>文件中(没有就自己新建一个)，使用<code>declare-styleable</code>标签自定义属性。</p>
<p>在attrs.xml里进行声明，其实都行，都是resourse，举例：</p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
    &lt;!--属性集合--&gt;
    &lt;declare-styleable name=&quot;SearchView&quot; &gt;
        &lt;!--hint--&gt;
        &lt;attr name=&quot;hint&quot; format=&quot;string&quot;/&gt;
        &lt;!--搜索图标  可以通过typedArray.getResourceId获取资源id--&gt;
        &lt;attr name=&quot;search_ico&quot; format=&quot;reference&quot; /&gt;
        &lt;!--清空图标--&gt;
        &lt;attr name=&quot;clear_ico&quot; format=&quot;reference&quot; /&gt;
        &lt;!--语音图标--&gt;
        &lt;attr name=&quot;voice_ico&quot; format=&quot;reference&quot; /&gt;
        &lt;!--输入类型--&gt;
        &lt;attr name=&quot;input_type&quot;&gt;
            &lt;!--value值只能是int类型的  所以获取时通过typeArray.getInt获取--&gt;
            &lt;enum name=&quot;text&quot; value=&quot;0&quot;/&gt;
            &lt;enum name=&quot;passwordText&quot; value=&quot;1&quot;/&gt;
        &lt;/attr&gt;

        &lt;attr name=&quot;gravity&quot;&gt;
            &lt;!--区别于enum  enum只能选择一个  flag可以多选 如：left|top--&gt;
            &lt;flag name=&quot;left&quot; value=&quot;0&quot; /&gt;
            &lt;flag name=&quot;top&quot; value=&quot;1&quot; /&gt;
            &lt;flag name=&quot;center&quot; value=&quot;2&quot; /&gt;
            &lt;flag name=&quot;right&quot; value=&quot;3&quot; /&gt;
            &lt;flag name=&quot;bottom&quot; value=&quot;4&quot; /&gt;
        &lt;/attr&gt;
    &lt;/declare-styleable&gt;

&lt;/resources&gt;</code></pre>
<p>其中<code>declare-styleable</code>标签代表一个属性集合，**<code>name</code>属性要与自定义的控件同名**。 <code>attr</code>则是每条属性了，<code>name</code>是属性值，<code>format</code>是指定属性类型,目前可支持11种类型：</p>
<blockquote>
<ul>
<li>reference:引用资源</li>
<li>string:字符串</li>
<li>Color：颜色</li>
<li>boolean：布尔值</li>
<li>dimension：尺寸值</li>
<li>float：浮点型</li>
<li>integer：整型</li>
<li>fraction：百分数</li>
<li>enum：枚举类型</li>
<li>flag：位或运算</li>
</ul>
</blockquote>
<ol>
<li>布局文件中使用</li>
</ol>
<p>首先需要加上一个命名空间<code>xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;</code> 然后直接利用这个命名空间设置属性即可</p>
<pre><code>&lt;com.searchview.SearchView
      android:id=&quot;@+id/searchView&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;50dp&quot;
      android:layout_marginEnd=&quot;8dp&quot;
      android:layout_marginStart=&quot;8dp&quot;
      android:layout_marginTop=&quot;8dp&quot;
      app:hint=&quot;aaa&quot;
      app:search_ico=&quot;@drawable/ic_search&quot;
      app:layout_constraintEnd_toEndOf=&quot;parent&quot;
      app:layout_constraintStart_toStartOf=&quot;parent&quot;
      app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;</code></pre>
<h3 id="测量"><a href="#测量" class="headerlink" title="测量"></a>测量</h3><p>测量是重点要掌握的，如果是ViewGroup则测量自己(设置自己大小，因为ViewGroup也可以是子view呀)跟设置期望孩子的大小。</p>
<p>如果是View则需要测量自己（设置自己大小）</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877fa2caab751?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>这两个参数要理解</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877fc3870f585?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877fee3eb06bc?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<h3 id="自定义控件的本质"><a href="#自定义控件的本质" class="headerlink" title="自定义控件的本质"></a>自定义控件的本质</h3><p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172878027202327b?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/06/12/Rxjava%E5%8F%AA%E7%9C%8B%E8%BF%99%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B0%B1%E5%A4%9F%E4%BA%86/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          Rxjava只看这一篇文章就够了
        
      </div>
    </a>
  
  
    <a href="/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B62/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">一文彻底了解Android自定义控件2</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=一文彻底了解Android自定义控件3 - ApocalypseBlog&url=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B63/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=一文彻底了解Android自定义控件3 - ApocalypseBlog&u=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B63/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=一文彻底了解Android自定义控件3 - ApocalypseBlog&url=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B63/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>